package com.cgt.xiaotao.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cgt.common.domain.dto.PageDTO;
import com.cgt.common.exception.BadRequestException;
import com.cgt.common.utils.BeanUtils;
import com.cgt.common.utils.CollUtils;
import com.cgt.common.utils.StringUtils;
import com.cgt.common.utils.UserContext;
import com.cgt.xiaotao.order.domain.dto.*;
import com.cgt.xiaotao.order.domain.po.Order;
import com.cgt.xiaotao.order.domain.po.OrderItem;
import com.cgt.xiaotao.order.domain.po.Payment;
import com.cgt.xiaotao.order.domain.query.OrderAdminQuery;
import com.cgt.xiaotao.order.domain.query.OrderPageQuery;
import com.cgt.xiaotao.order.domain.vo.*;
import com.cgt.xiaotao.order.mapper.OrderItemMapper;
import com.cgt.xiaotao.order.mapper.OrderMapper;
import com.cgt.xiaotao.order.mapper.PaymentMapper;
import com.cgt.xiaotao.order.service.IOrderService;
import com.cgt.xiaotao.order.util.SnowflakeIdGenerator;
import com.cgt.xiaotao.product.client.ProductFeignClient;
import com.cgt.xiaotao.product.client.domain.dto.Product;
import com.cgt.xiaotao.product.client.domain.vo.ProductVO;
import com.cgt.xiaotao.promotion.client.PromotionFeignClient;
import com.cgt.xiaotao.promotion.client.domain.dto.OrderProductDTO;
import com.cgt.xiaotao.promotion.client.domain.dto.ProductRequestDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    private final OrderItemMapper orderItemMapper;
    private final OrderMapper orderMapper;
    private final PaymentMapper paymentMapper;
    private final ProductFeignClient productFeignClient;
    private final SnowflakeIdGenerator idGenerator;
    private final PromotionFeignClient promotionFeignClient;

    // 创建订单快照
    @Override
    public OrderSnapshot createOrder(List<OrderItemDTO> orderItemDTOS, List<Long> couponIds) {
        // 1.获取用户id
        Long userId = UserContext.getUser();
        // 2.获取商品信息
        BigDecimal totalAmount = BigDecimal.ZERO;
        Map<Long, Product> productMap = new HashMap<>();
        for (OrderItemDTO orderItemDTO : orderItemDTOS) {
            Product product = productFeignClient.getProductById(orderItemDTO.getProductId());
            //将商品数量存入待保留字段type中
            product.setType(orderItemDTO.getQuantity().toString());
            productMap.put(orderItemDTO.getProductId(), product);
            totalAmount = totalAmount.add(product.getPrice().multiply(new BigDecimal(orderItemDTO.getQuantity())));
        }
        if (productMap.isEmpty() || productMap.size() != orderItemDTOS.size()) {
            throw new BadRequestException("库存不足！");
        }
        // 3.保存订单
        // 3.1 创建订单 order
        Order order = new Order();
        order.setUserId(userId);
        String orderNo = "XIAOTAO" + idGenerator.nextId();
        order.setOrderNo(orderNo);
        order.setTotalAmount(totalAmount);
        order.setStatus((byte) 0);
        order.setAddress(""); // 添加默认值
        order.setCouponIds(couponIds);
        this.save(order);

        Order orderOne = this.lambdaQuery()
                .eq(Order::getOrderNo, orderNo)
                .eq(Order::getUserId, userId)
                .one();

        // 3.2 创建订单项 order_item
        // 遍历productMap
        for (Map.Entry<Long, Product> entry : productMap.entrySet()) {
            OrderItem orderItem = new OrderItem();
            orderItem.setOrderId(orderOne.getId());
            orderItem.setProductId(entry.getKey());
            orderItem.setProductName(entry.getValue().getName());
            orderItem.setProductImage(entry.getValue().getImageUrl());
            orderItem.setPrice(entry.getValue().getPrice());
            orderItem.setQuantity(Integer.parseInt(entry.getValue().getType()));
            // 保存订单项到数据库
            orderItemMapper.insert(orderItem);
            // 4.删除购物车商品
            productFeignClient.deleteCart(entry.getKey());
        }
        OrderSnapshot orderSnapshot = new OrderSnapshot();
        orderSnapshot.setOrderNo(orderOne.getOrderNo());
        orderSnapshot.setUserId(orderOne.getUserId());
        // 5.返回结果
        return orderSnapshot;
    }

    @Override
    public OrderVO queryOrder(String orderNo) {
        // 1.获取用户id
        Long userId = UserContext.getUser();

        // 2.获取订单详情
        // 2.1 查询order表
        Order order = this.lambdaQuery().eq(Order::getOrderNo, orderNo)
                .eq(Order::getUserId, userId)
                .one();
        if (order == null) {
            return null;
        }

        // 手动解析coupon_ids - 如果为null则通过额外查询获取
        if (order.getCouponIds() == null || order.getCouponIds().isEmpty()) {
            try {
                String couponIdsJson = this.getBaseMapper().selectCouponIdsByOrderNoAndUserId(orderNo, userId);
                if (couponIdsJson != null && !couponIdsJson.isEmpty() && !"null".equals(couponIdsJson)) {
                    List<Long> couponIds = JSON.parseArray(couponIdsJson, Long.class);
                    order.setCouponIds(couponIds);
                }
            } catch (Exception e) {
                log.debug("查询优惠券ID列表失败 {}", e.toString());
                order.setCouponIds(new ArrayList<>());
            }
        }

        // 2.2 查询order_item表
        List<OrderItem> orderItemList = orderItemMapper.selectList(new QueryWrapper<OrderItem>().eq("order_id", order.getId()));
        // 2.3 封装productList
        List<ProductVO> productList = new ArrayList<>();
        for (OrderItem orderItem : orderItemList) {
            Product product = productFeignClient.getProductById(orderItem.getProductId());
            ProductVO productVO = BeanUtils.copyBean(product, ProductVO.class);
            productVO.setQuantity(orderItem.getQuantity());
            productList.add(productVO);
        }
        // 3.封装返回结果
        OrderVO orderVO = new OrderVO();
        orderVO.setOrderNo(order.getOrderNo());
        orderVO.setUserId(order.getUserId());
        orderVO.setTotalAmount(order.getTotalAmount());
        orderVO.setStatus(order.getStatus());
        orderVO.setAddress(order.getAddress());
        orderVO.setCreateTime(order.getCreateTime().toString());
        orderVO.setProductList(productList);
        orderVO.setCouponIds(order.getCouponIds());
        log.debug("查询优惠券使用列表 {}", order.getCouponIds());
        return orderVO;
    }

    @Override
    public PaymentSnapshot payment(PaymentDTO paymentDTO) {
        // 1.获取用户id
        Long userId = UserContext.getUser();
        // 2.获取订单详情
        Order order = this.lambdaQuery().eq(Order::getOrderNo, paymentDTO.getOrderNo()).one();
        if (order == null) {
            throw new BadRequestException("订单不存在！");
        }

        // 3.获取优惠券列表和商品列表
        // 获取最大优惠金额
        BigDecimal maxDiscountAmount = BigDecimal.ZERO;
        List<Long> couponIds = paymentDTO.getCouponIds();
        // 3.1 根据订单id查询order_item表获取商品列表
        List<OrderItem> orderItemList = orderItemMapper.selectList(new QueryWrapper<OrderItem>()
                .eq("order_id", order.getId()));
        if (couponIds != null && !couponIds.isEmpty()) {
            // 将List<OrderItem>转成List<OrderProductDTO>
            List<OrderProductDTO> orderProductDTOS = orderItemList.stream()
                    .map(orderItem -> {
                        OrderProductDTO orderProductDTO = new OrderProductDTO();
                        orderProductDTO.setProductId(orderItem.getProductId());
                        orderProductDTO.setQuantity(orderItem.getQuantity());
                        // 将价格从元转换为分，并确保结果为纯数字
                        BigDecimal priceInCents = orderItem.getPrice().multiply(new BigDecimal("100")).setScale(0, BigDecimal.ROUND_HALF_UP);
                        System.out.println("价格: " + priceInCents);
                        orderProductDTO.setPrice(priceInCents);
                        return orderProductDTO;
                    }).collect(Collectors.toList());

            // 3.2远程调用计算最大优惠金额
            ProductRequestDTO request = new ProductRequestDTO();
            request.setProducts(orderProductDTOS);
            request.setCouponIds(couponIds);
            BigDecimal maxDiscountAmountInCents = promotionFeignClient.getMaxDiscountAmount(request);
            System.out.println("最大优惠金额（分）: "+ maxDiscountAmountInCents);

            // 将最大优惠金额从分转换为元
            maxDiscountAmount = maxDiscountAmountInCents.divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
            System.out.println("最大优惠金额（元）: " + maxDiscountAmount);

            // 3.3删除已使用的优惠券
            for (Long couponId : couponIds) {
                try {
                    String id = couponId.toString();
                    log.info("准备使用优惠券，couponId: {}", couponId);
                    Boolean flag = promotionFeignClient.deleteUserCoupon(id);
                    log.info("优惠券使用结果，couponId: {}, result: {}", couponId, flag);
                    if (flag == null) {
                        log.warn("优惠券服务返回空结果，couponId: {}", couponId);
                        throw new BadRequestException("优惠券服务异常，优惠券ID: " + couponId);
                    }
                    if (!flag) {
                        log.warn("优惠券使用失败，couponId: {}", couponId);
                        throw new BadRequestException("优惠券使用失败，优惠券ID: " + couponId);
                    }
                } catch (Exception e) {
                    log.error("优惠券使用异常，couponId: {}", couponId, e);
                    if (e instanceof BadRequestException) {
                        throw e;
                    }
                    throw new BadRequestException("优惠券使用失败，优惠券ID: " + couponId + "，错误信息: " + e.getMessage());
                }
            }
        }

        // 4.封装结果
        PaymentSnapshot paymentSnapshot = new PaymentSnapshot();
        paymentSnapshot.setOrderNo(order.getOrderNo());
        paymentSnapshot.setDiscountAmount(maxDiscountAmount);
        log.debug("最大优惠金额 {}", maxDiscountAmount);
        paymentSnapshot.setTotalAmount(order.getTotalAmount().subtract(maxDiscountAmount));
        paymentSnapshot.setUserId(userId);
        paymentSnapshot.setName(paymentDTO.getName());
        paymentSnapshot.setPhone(paymentDTO.getPhone());
        paymentSnapshot.setAddress(paymentDTO.getAddress());
        paymentSnapshot.setRemark(paymentDTO.getRemark());
        paymentSnapshot.setPaymentMethod(paymentDTO.getPaymentMethod());
        paymentSnapshot.setCreateTime(new Date());

        // 5.保存记录
        Payment payment = new Payment();
        payment.setOrderId(order.getId());
        payment.setOrderNo(order.getOrderNo());
        payment.setUserId(order.getUserId());
        payment.setDiscountAmount(maxDiscountAmount); // 优惠金额
        payment.setTotalAmount(paymentSnapshot.getTotalAmount()); // 订单实际支付金额
        payment.setPaymentMethod(paymentSnapshot.getPaymentMethod()); // 支付方式
        payment.setStatus((byte) 0);    // 支付状态：未支付
        paymentMapper.insert(payment);

        // 更新订单
        order.setName(paymentDTO.getName());
        order.setPhone(paymentDTO.getPhone());
        order.setAddress(paymentDTO.getAddress());
        order.setRemark(paymentDTO.getRemark());
        // 更新订单的支付ID
        order.setPaymentId(payment.getId());
        order.setUpdateTime(new Date());
        this.updateById(order);

        // 6.返回结果
        return paymentSnapshot;
    }

    @Override
    public void updateOrder(OrderRenewDTO dto) {
        Long userId = UserContext.getUser();
        Order order = new Order();
        order.setAddress(dto.getAddress());
        order.setRemark(dto.getRemark());
        order.setName(dto.getName());
        order.setPhone(dto.getPhone());

        this.update(order, new UpdateWrapper<Order>()
                .eq("user_id", userId)
                .eq("order_no", dto.getOrderNo()));
    }

    @Override
    public PaymentVO queryPayment(String orderNo) {
        Payment payment = paymentMapper.selectOne(new QueryWrapper<Payment>().eq("order_no", orderNo));
        if (payment == null) {
            throw new BadRequestException("未找到支付信息");
        }
        Order order = this.getOne(new QueryWrapper<Order>().eq("order_no", orderNo));
        if (order == null) {
            throw new BadRequestException("订单不存在");
        }
        List<OrderItem> orderItems = orderItemMapper.selectList(new QueryWrapper<OrderItem>().eq("order_id", order.getId()));
        if (CollUtils.isEmpty(orderItems)) {
            throw new BadRequestException("订单商品不存在");
        }
        // 更新订单支付状态
        this.lambdaUpdate()
                .eq(Order::getOrderNo, orderNo)
                .set(Order::getUpdateTime, new Date())
                .set(payment.getStatus() == (byte) 1, Order::getStatus, (byte)1)
                .update();

        PaymentVO vo = new PaymentVO();
        vo.setOrderNo(orderNo);     // 订单编号
        vo.setDiscountAmount(payment.getDiscountAmount());  // 优惠金额
        vo.setPayAmount(payment.getTotalAmount());  // 支付金额
        vo.setTotalAmount(payment.getTotalAmount().add(payment.getDiscountAmount()));  // 订单总金额
        vo.setPayStatus(payment.getStatus());   // 支付状态
        // 修复空指针异常：检查payTime是否为null
        vo.setPayTime(payment.getPayTime() != null ? payment.getPayTime().toString() : "");     // 支付时间

        vo.setPaymentMethod(payment.getPaymentMethod());   // 支付方式

        vo.setName(order.getName());    // 收货人姓名
        vo.setPhone(order.getPhone());      // 收货人手机号
        vo.setAddress(order.getAddress());  // 收货地址
        vo.setRemark(order.getRemark());    // 订单备注

        // 将List<OrderItem> 转换成List<OrderItemDTO>
        List<OrderItemDTO> products = new ArrayList<>();
        orderItems.forEach(orderItem -> {
            OrderItemDTO orderItemDTO = new OrderItemDTO();
            orderItemDTO.setProductId(orderItem.getProductId());
            orderItemDTO.setName(orderItem.getProductName());
            orderItemDTO.setImageUrl(orderItem.getProductImage());
            orderItemDTO.setPrice(orderItem.getPrice());
            orderItemDTO.setQuantity(orderItem.getQuantity());
            products.add(orderItemDTO);
        });
        vo.setProducts(products);

        return vo;
    }

    @Override
    public PageDTO<OrderListVO> selectPage(OrderPageQuery query) {
        Long userId = UserContext.getUser();
        log.info("订单分页查询参数: userId={}, query={}", userId, query);

        if (query.getSortBy() == null) {
            query.setSortBy("create_time");
        }
        if (query.getIsAsc() == null) {
            query.setIsAsc(true);
        }

        // 计算偏移量
        long offset = (query.getPageNo() - 1) * query.getPageSize();
        String sortOrder = query.getIsAsc() ? "ASC" : "DESC";
        String sortBy = convertSortByField(query.getSortBy());

        // 查询总数
        long total = orderMapper.countWithSql(userId, query.getStatus());

        // 查询当前页数据
        List<Order> orders = orderMapper.selectPageWithSql(
                userId,
                query.getStatus(),
                sortBy,
                sortOrder,
                offset,
                query.getPageSize()
        );

        // 构造MyBatis Plus Page对象用于返回
        Page<Order> page = new Page<>(query.getPageNo(), query.getPageSize());
        page.setRecords(orders);
        page.setTotal(total);

        // 计算总页数
        long pages = (total + query.getPageSize() - 1) / query.getPageSize();
        page.setPages(pages);

        log.info("订单分页查询结果: 总记录数={}, 总页数={}, 当前页码={}, 当前页记录数={}",
                page.getTotal(), page.getPages(), page.getCurrent(), page.getRecords().size());

        List<OrderListVO> voList = page.getRecords().stream().map(order -> {
            OrderListVO vo = new OrderListVO();
            vo.setOrderNo(order.getOrderNo());
            vo.setStatus(order.getStatus());
            vo.setAddress(order.getAddress());
            vo.setPhone(order.getPhone());
            vo.setName(order.getName());
            vo.setCreateTime(order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            return vo;
        }).collect(Collectors.toList());

        return PageDTO.of(page, voList);
    }

    /**
     * 转换排序字段名，防止SQL注入
     * @param sortBy 原始排序字段名
     * @return 转换后的字段名
     */
    private String convertSortByField(String sortBy) {
        if (sortBy == null) {
            return "create_time";
        }

        switch (sortBy) {
            case "id":
                return "id";
            case "orderNo":
                return "order_no";
            case "totalAmount":
                return "total_amount";
            case "status":
                return "status";
            case "createTime":
                return "create_time";
            case "updateTime":
                return "update_time";
            default:
                return "create_time";
        }
    }

    @Override
    public OrderItemVO getOrderItem(String orderNo) {
        Order order = this.getOne(new QueryWrapper<Order>().eq("order_no", orderNo));
        if (order == null) {
            throw new BadRequestException("订单不存在");
        }
        OrderItemVO vo = new OrderItemVO();
        vo.setOrderNo(order.getOrderNo());
        vo.setName(order.getName());
        vo.setPhone(order.getPhone());
        vo.setAddress(order.getAddress());
        vo.setCreateTime(order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        vo.setStatus(order.getStatus());
        vo.setTotalAmount(order.getTotalAmount());
        List<OrderItem> orderItems = orderItemMapper.selectList(new QueryWrapper<OrderItem>().eq("order_id", order.getId()));
        List<ProductItemDTO> products = orderItems.stream().map(orderItem -> {
            ProductItemDTO productItemDTO = new ProductItemDTO();
            productItemDTO.setProductId(orderItem.getProductId());
            productItemDTO.setName(orderItem.getProductName());
            productItemDTO.setImageUrl(orderItem.getProductImage());
            productItemDTO.setPrice(orderItem.getPrice());
            productItemDTO.setQuantity(orderItem.getQuantity());
            return productItemDTO;
        }).collect(Collectors.toList());
        vo.setProductList(products);
        return vo;
    }

    @Override
    public PageDTO<OrderAdminDTO> selectAdminPage(OrderAdminQuery query) {
        if (StringUtils.isBlank(query.getSortBy())) {
            query.setSortBy("create_time");
        }
        if (query.getIsAsc() == null) {
            query.setIsAsc(true);
        }
        Page<Order> page = this.lambdaQuery()
                .like(StringUtils.isNotBlank(query.getOrderNo()), Order::getOrderNo, query.getOrderNo())
                .like(StringUtils.isNotBlank(query.getName()), Order::getName, query.getName())
                .like(StringUtils.isNotBlank(query.getPhone()), Order::getPhone, query.getPhone())
                .page(query.toMpPage(query.getSortBy(), query.getIsAsc()));
        if (CollUtils.isEmpty(page.getRecords())) {
            return PageDTO.empty(page);
        }
        List<OrderAdminDTO> voList = BeanUtils.copyList(page.getRecords(), OrderAdminDTO.class);
        return PageDTO.of(page, voList);
    }
}
